package com.osexp.model;

import java.util.HashMap;

import java.util.Map;
import java.util.Vector;

public class Memory implements paraConstants{
	//物理内存实体
	Integer aPhysicalMem[]=new Integer[iFrameNumber];
	
	//用于FIFO算法
	Vector<Integer> vLRU=null;
	
	//存放pageTable
	Map<Integer,pageTable> map = new HashMap<Integer,pageTable>();
	
	private int fifoCurr;
	private int[] fifoCurrPart;
	private Vector<Vector<Integer>> vLRUPart;
	
	public Memory() {
		super();
		
		
		vLRU=new Vector<Integer>();
		vLRUPart= new Vector<Vector<Integer>>();
		
		fifoCurr=0;
		fifoCurrPart=new int[5];
		for(int i=0;i<5;i++){
			fifoCurrPart[i]=0;	
			Vector<Integer> temp=new Vector<Integer>();
			for(int i2=0;i2<4;i2++){
				temp.add(i2);
			}
			vLRUPart.add(temp);
		}
		for(int i=0;i<iFrameNumber;i++){
			aPhysicalMem[i]=0;
			vLRU.add(i);
		}
	}
		
	public void memUpdate(Integer pageTableIdx,int iLogicalAddress,int iPhysicalAddress){
		pageTable ptb=map.get(pageTableIdx);
		ptb.update(iLogicalAddress, iPhysicalAddress);		
	}
	
	public int fifoFind(Integer pageTableIdx,int iLogicalAddress){
		pageTable ptb=map.get(pageTableIdx);
		if(ptb==null){
			System.out.println("Map error===============");
		}
		int iPhysicalAddress=ptb.find(iLogicalAddress);
		if(iPhysicalAddress==-1){
			//Not Found		
			ptb.add(iLogicalAddress, fifoCurr);
			aPhysicalMem[fifoCurr]=iLogicalAddress;
			fifoCurr=(fifoCurr+1)%iFrameNumber;			
		}else{
			//Found
		}
		return iPhysicalAddress;
	}
	
	public int lruFind(Integer pageTableIdx,int iLogicalAddress){
		pageTable ptb=map.get(pageTableIdx);
		if(ptb==null){
			System.out.println("Map error===============");
		}
		int iPhysicalAddress=ptb.find(iLogicalAddress);
		if(iPhysicalAddress==-1){
			//Not Found
			fifoCurr=vLRU.firstElement();
			ptb.add(iLogicalAddress, fifoCurr);			
			aPhysicalMem[fifoCurr]=iLogicalAddress;	
			vLRU.removeElementAt(0);
			vLRU.add(fifoCurr);
		}else{
			//Found
			int idx2=vLRU.indexOf(iPhysicalAddress);			
			vLRU.removeElementAt(idx2);
			vLRU.add(iPhysicalAddress);
		}
		return iPhysicalAddress;
	}
	
	public int fifoFindPart(Integer pageTableIdx,int iLogicalAddress){
		pageTable ptb=map.get(pageTableIdx);
		if(ptb==null){
			System.out.println("Map error===============");
		}
		int iPhysicalAddress=ptb.find(iLogicalAddress);
		if(iPhysicalAddress==-1){
			//Not Found
			ptb.add(iLogicalAddress, fifoCurr);
			aPhysicalMem[fifoCurrPart[pageTableIdx]+4*pageTableIdx]=iLogicalAddress;
			fifoCurrPart[pageTableIdx]=(fifoCurrPart[pageTableIdx]+1)%4;
		}else{
			//Found
		}
		return iPhysicalAddress;
	}
	
		
	public int lruFindPart(Integer pageTableIdx,int iLogicalAddress){
		pageTable ptb=map.get(pageTableIdx);
		if(ptb==null){
			System.out.println("Map error===============");
		}
		int iPhysicalAddress=ptb.find(iLogicalAddress);
		if(iPhysicalAddress==-1){
			//Not Found
			
			Vector<Integer> vTemp=vLRUPart.get(pageTableIdx);
			int idxTemp=vTemp.firstElement();
			ptb.add(iLogicalAddress,idxTemp+4*pageTableIdx);
			aPhysicalMem[idxTemp+4*pageTableIdx]=iLogicalAddress;			
			vLRUPart.get(pageTableIdx).removeElementAt(0);
//			System.out.println("=====================idx==="+);
			vLRUPart.get(pageTableIdx).add(idxTemp);			
		}else{
			//Found
			Vector<Integer> vTemp=vLRUPart.get(pageTableIdx);
			int rmIdxTemp=vTemp.indexOf(iPhysicalAddress%4);			
			vLRUPart.get(pageTableIdx).removeElementAt(rmIdxTemp);
			vLRUPart.get(pageTableIdx).add(iPhysicalAddress%4);		
		}
		return iPhysicalAddress;
	}
	
	public void addPageTable(Integer pageTableIdx) {
		pageTable ptb=new pageTable();
		map.put(pageTableIdx, ptb);		
	}		
	public String printPhysicalMemory(){
		System.out.println(aPhysicalMem);
		String temp="[PhysicalMems=" ;
		for(int i=0;i<aPhysicalMem.length;i++){
			if(i%4==0)
				temp+="\n";
			temp += aPhysicalMem[i]+"\t";
		}
		temp+="]";
		return temp;
	}
}
